package com.xh;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import com.xh.bussiness.permission.intercept.LoginTokenInterceptor;
import com.xh.bussiness.permission.intercept.PermisstionInterceptor;
import com.xh.core.handler.XhMetaObjectHandler;
import com.xh.core.intercept.TokenInterceptor;
import org.hibernate.validator.HibernateValidator;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import java.time.Duration;
import java.util.Properties;

@EnableScheduling
@EnableTransactionManagement
@SpringBootApplication
@EnableAsync //开启异步调用
//@ComponentScan(basePackages = {"com.xh.bussiness.*.service.impl","com.xh.bussiness.*.controller","cn.binarywang.wx.miniapp.api.*"})
@MapperScan({"com.xh.bussiness.*.dao","com.xh.one2one.*.dao"})
public class ApplicationConfig extends SpringBootServletInitializer implements WebMvcConfigurer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        application.sources(ApplicationConfig.class);
        return super.configure(application);
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("swagger-*/**")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    @Bean
    public ISqlInjector sqlInjector(){
        return new LogicSqlInjector();
    }

    @Bean
    public MetaObjectHandler metaObjectHandler(){
        return new XhMetaObjectHandler();
    }

    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
    @Bean
    public Validator validator(){
        ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
                .configure()
                .addProperty( "hibernate.validator.fail_fast", "true" )
                .buildValidatorFactory();
        Validator validator = validatorFactory.getValidator();

        return validator;
    }


    @Bean
    public DefaultKaptcha producer() {
        Properties properties = new Properties();
//        properties.put("kaptcha.border", "no");
//        properties.put("kaptcha.textproducer.font.color", "black");
//        properties.put("kaptcha.textproducer.char.space", "10");
//        properties.put("kaptcha.textproducer.char.length","4");
//        properties.put("kaptcha.image.height","34");
//        properties.put("kaptcha.textproducer.font.size","25");

        properties.put("kaptcha.noise.impl","com.google.code.kaptcha.impl.NoNoise");
        Config config = new Config(properties);
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
    @Bean
    public LoginTokenInterceptor loginTokenInterceptor(){
        return new LoginTokenInterceptor();
    }
    @Bean
    public PermisstionInterceptor permisstionInterceptor(){
        return new PermisstionInterceptor();
    }

    @Bean
    public TaskScheduler scheduledExecutorService() {
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        scheduler.setPoolSize(8);
        scheduler.setThreadNamePrefix("scheduled-thread-");
        return scheduler;
    }
    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
        RestTemplate restTemplate = restTemplateBuilder
                .setConnectTimeout(30000)
                .setReadTimeout(30000)
                .build();
        return restTemplate;
    }
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new TokenInterceptor()).addPathPatterns("/admin/**");
        String[] excludePaths = {
                "/crm/clue/submitApply",
                "/crossdomain.xml",
                "/swagger-ui.html",
                "/swagger-resources/**",
                "/swagger*/**",
                "/webjars/**",
                "/grading/**",
                "/v2/**",
                "/wx/**",
                "/static/**",
                "/system/file/**",
                "/kaptcha/**",
                "/sms/**",
                "/xkw/callback/**",
                "/xkw/api/**",
                "/MP_verify_He5yHspimxQBNzv0.txt",
                "/upload/**",
                "/system/ueditor/**",
                "/permission/auth/getWxLoginInfo",
                "/permission/auth/getWxUserPhone",
                "/tools/getData/*"
        };
        registry.addInterceptor(loginTokenInterceptor()).excludePathPatterns(excludePaths);
        String[] excludePermisstionPaths = {
                "/",
                "/static/**",
                "/upload/**",
                "/toLogin",
                "/toFrameLogin",
                "/admin/toLogin",
                "/admin/toFrameLogin",
                "/login",
                "/xkw/callback/**",
                "/xkw/api/**",
                "/admin/login",
                "/grading/**",
                "/admin/main",
                "/system/ueditor/**",
                "/permission/auth/getWxLoginInfo",
                "/permission/auth/getWxUserPhone",
        };
        registry.addInterceptor(permisstionInterceptor()).excludePathPatterns(excludePermisstionPaths);

    }

    public static void main(String[] args) throws Exception {
        SpringApplication app = new SpringApplication(ApplicationConfig.class);
        app.setBannerMode(Banner.Mode.CONSOLE);
        app.run(args);
    }

//    @Override
//    public void addCorsMappings(CorsRegistry registry) {
//        registry.addMapping("/**")
//                .allowedOrigins("*")
//                .allowedMethods("GET","HEAD","POST","PUT","DELETE","OPTIONS")
//                .allowCredentials(true)
//                .maxAge(3600)
//                .allowedHeaders("*");
//    }

}
